-- The MIT License (MIT)
-- Copyright (c) 2016 Yanghe Sun

--luacheck: no global
--luacheck: no unused args

local luaunit = require("luaunit")
local jdcore  = require("jdcore")

Test_jdcore = {}
local tmp_files = require("tmp_files")

local function createtemp(data)
    local name = os.tmpname();
    local f = io.open(name, "w");
    f:write(data);
    f:close();
    table.insert(tmp_files, { name, io.open(name) });

    return tmp_files[#tmp_files][2];
end

function Test_jdcore:testInvaildFunc()
    luaunit.assertIsNil(jdcore.GetJudgeFunc("stupid"));
end

function Test_jdcore:testVaildFunc()
    luaunit.assertIsFunction(jdcore.GetJudgeFunc("byte"));
    luaunit.assertIsFunction(jdcore.GetJudgeFunc("fulltext"));
    luaunit.assertIsFunction(jdcore.GetJudgeFunc("double", 0.001));
    luaunit.assertIsFunction(jdcore.GetJudgeFunc("token"));
end

function Test_jdcore:testByte()
    local comp_byte = jdcore.GetJudgeFunc("byte");

    local stdout  = createtemp("abcdefg");
    local output1 = createtemp("abcdefg");
    local output2 = createtemp("abcdefgh");
    local output3 = createtemp("abcdef\ng");
    local output4 = createtemp("abcdefg ");

    luaunit.assertEquals(comp_byte(stdout, output1).ac, true); stdout:seek("set");
    luaunit.assertEquals(comp_byte(stdout, output2).ac, false); stdout:seek("set");
    luaunit.assertEquals(comp_byte(stdout, output3).ac, false); stdout:seek("set");
    luaunit.assertEquals(comp_byte(stdout, output4).ac, false);
end

function Test_jdcore:testFullText()
    local comp_ft = jdcore.GetJudgeFunc("fulltext");

    local stdout  = createtemp("abcdefg");
    local output1 = createtemp("abcdefg");
    local output2 = createtemp("abcdefgh");
    local output3 = createtemp("abcdef\ng");
    local output4 = createtemp("abcdefg ");

    luaunit.assertEquals(comp_ft(stdout, output1).ac, true); stdout:seek("set");
    luaunit.assertEquals(comp_ft(stdout, output2).ac, false); stdout:seek("set");
    luaunit.assertEquals(comp_ft(stdout, output3).ac, false); stdout:seek("set");
    luaunit.assertEquals(comp_ft(stdout, output4).ac, true);
end

function Test_jdcore:testDouble()
    local comp_db = jdcore.GetJudgeFunc("double", 0.0001);

    local stdout  = createtemp("1.0001");
    local output1 = createtemp("1");
    local output2 = createtemp("2");
    local output3 = createtemp("-2147483647");
    local output4 = createtemp("1.00010");

    luaunit.assertEquals(comp_db(stdout, output1).ac, true); stdout:seek("set");
    luaunit.assertEquals(comp_db(stdout, output2).ac, false); stdout:seek("set");
    luaunit.assertEquals(comp_db(stdout, output3).ac, false); stdout:seek("set");
    luaunit.assertEquals(comp_db(stdout, output4).ac, true);
end

function Test_jdcore:testToken()
    local comp_tk = jdcore.GetJudgeFunc("token");

    local stdout  = createtemp("a b c d e");
    local output1 = createtemp("a b c d e");
    local output2 = createtemp("a c b d e");
    local output3 = createtemp("a b c d e f");
    local output4 = createtemp("a\nb\nc   d e");

    luaunit.assertEquals(comp_tk(stdout, output1).ac, true); stdout:seek("set");
    luaunit.assertEquals(comp_tk(stdout, output2).ac, false); stdout:seek("set");
    luaunit.assertEquals(comp_tk(stdout, output3).ac, false); stdout:seek("set");
    luaunit.assertEquals(comp_tk(stdout, output4).ac, true);
end

function Test_jdcore:testSPJ()
    local spj_code = io.open("./testcases/spj.lua"):read("*a");
    local comp_spj = jdcore.GetJudgeFunc("spj", spj_code);

    local stdout  = createtemp("abcdefg");
    local output1 = createtemp("abcdegf");
    local output2 = createtemp("abcdefgh");
    local output3 = createtemp("1111111");

    local inputno  = createtemp("no");
    local inputok  = createtemp("ok");

    luaunit.assertEquals(comp_spj(stdout, output1, inputok).ac, true); stdout:seek("set");
    luaunit.assertEquals(comp_spj(stdout, output2, inputok).ac, false); stdout:seek("set");
    luaunit.assertEquals(comp_spj(stdout, output3, inputok).ac, true); stdout:seek("set");
    luaunit.assertEquals(comp_spj(stdout, output3, inputno).ac, false);
end
